package TorrentClient;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.regex.Pattern;
import java.io.*;

public class ClientThread extends Thread{
	ServerSocket temp = null;
	Socket tempSeocket;
    public ClientThread(int port) throws BindException {
        super();
        try {
			temp = new ServerSocket(port);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    public void run() {
    	while(true){
    		
				try {
					GUI.updateConsole("Listening to requests");
					Socket peerSocket = temp.accept();
					BufferedReader socketReader = new BufferedReader(new InputStreamReader(peerSocket.getInputStream()));
					String command = socketReader.readLine();
					System.out.println("Command: "+command);
					if(command.equalsIgnoreCase("synch")){
						//retreive peer list
						GUI.updateConsole("Accepted connection from tracker: "+peerSocket.getInetAddress().getHostAddress());
						String fileInfo = socketReader.readLine();
						GUI.updateConsole("Requesting file: "+fileInfo);
						String peersList = socketReader.readLine();
						if(peersList == null){
							GUI.updateConsole("There are no peers with your files");
						}
						else{
							String peersArray[]= peersList.split(",");
							for(int i=0; i<peersArray.length; i++){
								this.requestFile(peersArray[i],fileInfo);
							}
							
						}
						
					}
					if(command.startsWith("request")){
						//requested a file I have
						GUI.updateConsole("Requested file from peer: "+peerSocket.getInetAddress().getHostAddress());
						Socket socket = new Socket(peerSocket.getInetAddress().getHostAddress(),50000);
						String fileName = command.split(Pattern.quote("|"))[1];
						PrintWriter socketWriter = new PrintWriter(socket.getOutputStream());
						File transfer = new File(fileName);
						socketWriter.println("SendFile|"+fileName+"|"+transfer.length());
						socketWriter.flush();
						long size = transfer.length();
						GUI.updateConsole("File information sent to: "+peerSocket.getInetAddress().getHostAddress());
						InputStream in = new FileInputStream(transfer);
										
						OutputStream output = socket.getOutputStream();
						
						byte[] buff = new byte[socket.getSendBufferSize()];
						int bytesRead = 0;
						long totalBytes = 0;
						System.out.println(transfer.length()+ " bytes");
						GUI.updateProgressBar(0);
						while((bytesRead = in.read(buff))>0)
						{
							output.write(buff,0,bytesRead);
							totalBytes += bytesRead;
							GUI.updateProgressBar(this.getProportion(size, totalBytes));
						}
						in.close();
						socket.close();
						output.close();
					      
					     
						
					}
					if(command.startsWith("SendFile")){
						//Receive file
						GUI.updateConsole("Receiving file from: "+peerSocket.getInetAddress().getHostAddress());
						GUI.updateConsole("Size: "+command.split(Pattern.quote("|"))[2]);
						String fileName = command.split(Pattern.quote("|"))[1];
						long size = Long.parseLong(command.split(Pattern.quote("|"))[2]);
						InputStream input = peerSocket.getInputStream();
					    FileOutputStream fos = new FileOutputStream(fileName);
					    byte[] outBuffer = new byte[peerSocket.getReceiveBufferSize()];
					    int bytesReceived=0;
					    long totalBytes = 0;
					   GUI.progressBar.setValue(0);
					    int counter =0;
					    while((bytesReceived = input.read(outBuffer))>0){
					    	fos.write(outBuffer,0,bytesReceived);
					    	totalBytes+=bytesReceived;
					    	GUI.progressBar.setValue(this.getProportion(size, totalBytes));
					    	
					    }
					    fos.close();
					    input.close();
					    peerSocket.close();
					    
					  }
					
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			
    	}
    }
    
    public int getProportion(long FileSize, long actualsize){
    	return (int) (actualsize*100/FileSize);
    }
    public void requestFile(String ipAddress, String fileName){
    	
    	int port =50000;
    	try {
			Socket socket = new Socket(ipAddress,port);
			PrintWriter socketWriter = new PrintWriter(socket.getOutputStream());
			socketWriter.println("request|"+fileName);
			socketWriter.flush();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    }
    
  
   
}
